chore: phase 1 cleanup — vendor deps, dev tooling, tests, CI#7
Open
llacoste wants to merge 4 commits into
Open
chore: phase 1 cleanup — vendor deps, dev tooling, tests, CI#7llacoste wants to merge 4 commits into
llacoste wants to merge 4 commits into
Conversation
Brings the site closer to "still works in 10 years with no network" by removing the two remaining runtime CDN dependencies, and adds a standard dev-tooling baseline (Vitest + Playwright + ESLint + Prettier) so future cleanup can move safely. - Vendored jspdf 2.5.1 and Font Awesome Free 6.7.2 (solid + brands) under assets/vendor/; index.html now loads them locally. - VENDOR.md records source URL, version, and SHA256 for every vendored library so refreshes are reproducible. - Vitest covers pure helpers (linspace, getSum, compareMul, compareAbsdiff, subtractArraysSimple, makeArr) via a small vm-based shim so source files can stay as <script>-tag globals for now (Phase 5 will modularize). - Playwright pins the string-art algorithm's output: runs the generator against mandala_close.jpg with fixed parameters and snapshots the resulting line_sequence. This is the regression test for the algorithm itself ahead of Phase 3's planned numjs/opencv removal. - ESLint config is permissive about the script-tag architecture (allows cross-file globals) but strict about no-undef — catches the kind of loop-counter leaks fixed in the follow-up commit. - Pinned Node to 20.10.0 via .tool-versions (the only version installed via asdf locally). - Removed assets/.DS_Store; .gitignore covers further leaks.
Loop counters and intermediate vars were being assigned without let/var/const, leaking to window on every iteration. ESLint's no-undef flagged 173 of them. The leaks were benign in practice — the leaked names happened not to collide with anything — but they're a tripwire for future edits, and at least one (the `weight` local in NonBlockingLineCalculator) shadowed nothing only by accident. The algorithm output is unchanged: the Playwright snapshot test (test/e2e/algorithm_snapshot.spec.js) produces a byte-identical line_sequence before and after this change. Prettier formatting is bundled in because the lint clean-up touched most of the same lines anyway.
Single-stage pipeline (Verify only). Digital Ocean handles deploy out of band via auto-pull on master, so CI's only job is gating that push. Verify fans into a matrix of four phases — Format, Lint, Unit, E2E — matching the convert_to_hex pattern. E2E is the slow one (~12s plus browser install), so the Playwright browser bundle is cached on package-lock to keep cold runs reasonable. Dependabot tracks github-actions and the npm dev tooling weekly. The runtime libraries under assets/vendor/ are intentionally NOT tracked — those refresh manually with checksum updates in VENDOR.md.
The CI run on Linux was failing because Playwright's default snapshot
path appends `-{projectName}-{platform}`, so a snapshot generated on
macOS as `mandala-close-100segments-chromium-darwin.json` wasn't found
when CI looked for `…-chromium-linux.json`.
Verified by generating the Linux snapshot inside the official
mcr.microsoft.com/playwright:v1.60.0-jammy container — the output was
byte-identical to the darwin one, confirming the algorithm is platform
invariant.
Stripped the suffix via snapshotPathTemplate so one fixture serves all
runners. If a future change ever introduces real platform divergence,
the test will fail loudly and we can re-add the suffix then.
Also aligned the test's `toMatchSnapshot` arg to the sanitized filename
Playwright actually writes (`_` → `-`), so the lookup and the fixture
on disk stay in sync.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of the threadscape cleanup. Foundational work — vendors the remaining CDN runtime deps, adds a dev-tooling baseline, pins the string-art algorithm's behavior with a snapshot test, and fixes a wave of implicit-global leaks the linter surfaced.
Nothing about the deployed artifact changes shape: still a static site, still served from repo root, still triggered by Digital Ocean's auto-pull on master. The runtime no longer makes any third-party CDN requests.
The first three commits each tell a self-contained story; the branch is best reviewed commit-by-commit:
chore: vendor CDN deps and add dev tooling— gitignore, Node pin, Vitest/Playwright/ESLint/Prettier, vendored jspdf 2.5.1 + Font Awesome Free 6.7.2,VENDOR.mdwith SHA256s, unit tests for pure helpers, Playwright snapshot for the algorithm output.fix: scope implicit globals and apply Prettier formatting— addslet/constto 173 leaked loop counters and intermediate vars instring_art_generator.jsandwalkthrough.js. Snapshot test verifies byte-identical algorithm output. Prettier formatting bundled in.ci: add Verify-stage GitHub Actions workflow + Dependabot— single-stage matrix (Format / Lint / Unit / E2E), follows theconvert_to_hexpattern. Dependabot tracks GH Actions + npm dev deps weekly; vendored libs are intentionally excluded (those refresh manually viaVENDOR.md).Test plan
npm run format:check— cleannpm run lint— 0 errors, 23 warnings (all dead-code surface area; Phase 5 input)npm test— 14/14 unit tests passnpm run test:e2e— 1/1 Playwright snapshot passes;line_sequenceis byte-identical before and after the implicit-globals fixRisks
line_sequencebyte-for-byte. If the snapshot drifts in a future change, that's the signal to investigate before blessing.index.htmlnow loads Font Awesome and jspdf fromassets/vendor/instead of CDNs. Verified visually that all icons (fa-arrow-down,fa-rotate-left,fa-github-square, etc.) still render and thatgeneratePDFstill produces a downloadable PDF.package.json,node_modules, configs) are inert on the static host or gitignored.Phase 1 of N
The followup phases planned in the design conversation:
docs/algorithm.mdexplaining whatstring_art_generator.jsactually does; rename single-letter vars (R→grayscale_image,l→line_index, etc.).Uint8Array/Float64Array+ raw 2D canvas. Drops ~9.3 MB of vendored code.setTimeout(0)chunking.startDrawing,pinsOutputreferences), fix the cropper-singleton TODO, wire up or hide thenot_yet_implementedUI options, modularize.